package com.rpay.common.util.http.builder;

import com.rpay.common.util.http.exception.HttpProcessException;
import com.rpay.common.util.http.request.HttpSsl;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;

/**
 * @author： 
 * @date： 2017/9/20
 * @desc：HTTP客户端构造器
 */
public class HttpClientxBuilder extends HttpClientBuilder {

    /**
     * 用于配置ssl
     */
    private HttpSsl ssl = HttpSsl.getInstance();

    /**
     * ssl 协议版本
     */
    private HttpSsl.SSLProtocolVersion sslpv = HttpSsl.SSLProtocolVersion.SSLv3;

    public static HttpClientxBuilder custom() throws HttpProcessException {
        return new HttpClientxBuilder()
                .pool(400, 100)
                .timeout(30000)
                .retry(2)
                ;
    }

    /**
     * 设置超时时间以及是否允许网页重定向（自动跳转 302）
     *
     * @param timeout 超时时间，单位-毫秒
     * @return
     */
    public HttpClientxBuilder timeout(int timeout) {
        // 配置请求的超时设置
        RequestConfig config = RequestConfig.custom()
                .setConnectionRequestTimeout(timeout)
                .setConnectTimeout(timeout)
                .setSocketTimeout(timeout)
                // 超时之后是否自动跳转
                .setRedirectsEnabled(false)
                .build();
        return (HttpClientxBuilder) this.setDefaultRequestConfig(config);
    }

    /**
     * 设置ssl安全链接
     *
     * @return
     * @throws HttpProcessException
     */
    public HttpClientxBuilder ssl() throws HttpProcessException {
        return (HttpClientxBuilder) this.setSSLSocketFactory(ssl.getSSLCONNSF(sslpv));
    }

    /**
     * 设置自定义sslcontext
     *
     * @param keyStorePath 密钥库路径
     * @param keyStorepass 密钥库密码
     * @return
     * @throws HttpProcessException
     */
    public HttpClientxBuilder ssl(String keyStorePath, String keyStorepass) throws HttpProcessException {
        this.ssl = HttpSsl.custom().customSSL(keyStorePath, keyStorepass);
        return ssl();
    }

    /**
     * 设置连接池（默认开启https）
     *
     * @param maxTotal           最大连接数
     * @param defaultMaxPerRoute 每个路由默认连接数
     * @return
     * @throws HttpProcessException
     */
    public HttpClientxBuilder pool(int maxTotal, int defaultMaxPerRoute) throws HttpProcessException {
        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder
                .<ConnectionSocketFactory>create()
                .register("http", PlainConnectionSocketFactory.INSTANCE)
                .register("https", ssl.getSSLCONNSF(sslpv)).build();
        //设置连接池大小
        PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
        connManager.setMaxTotal(maxTotal);
        connManager.setDefaultMaxPerRoute(defaultMaxPerRoute);
        return (HttpClientxBuilder) this.setConnectionManager(connManager);
    }

    /**
     * 重试（如果请求是幂等的，就再次尝试）
     *
     * @param tryTimes 重试次数
     * @return
     */
    public HttpClientxBuilder retry(final int tryTimes) {
        // 请求重试处理
        return (HttpClientxBuilder) this.setRetryHandler(new DefaultHttpRequestRetryHandler(tryTimes, false));
    }
}
